package com.panghl;

import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;

import java.io.InputStream;
import java.io.OutputStream;

/**
 * minio操作文件工具类
 */
@Slf4j
public class MinioFileUtil {

    private static String endpoint = "http://10.147.17.170:9000";
    private static String accessKey = "admin";
    private static String secretKey = "12345678";
    private static String bucketName = "test";


    public MinioClient gainMinioClient() {
        return MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
    }

    /**
     * 删除指定的文件
     *
     * @param filePath 要被删除的文件路径，不能为空（eg: 201403/1910585304069fdj.png）
     * @throws Exception
     */
    public void deleteFile(String filePath) throws Exception {
        if (StringUtils.isBlank(filePath)) {
            log.error("要被删除的文件路径不能为空");
            return;
        }

        // 获取连接
        MinioClient minioClient = gainMinioClient();
        if (minioClient == null) {
            log.error("获取minio连接失败");
            return;
        }
        minioClient.removeObject(RemoveObjectArgs
                .builder()
                .bucket(bucketName)
                .object(filePath)
                .build());
    }

    /**
     * 上传文件
     *
     * @param filePath 要被上传文件的路径，不能为空（eg: 201403/1910585304069fdj.png）
     * @param ins      要被上传文件的输入流，不能为空
     */
    public void uploadFile(String filePath, InputStream ins) throws Exception {
        if (StringUtils.isBlank(filePath)) {
            log.error("要被上传的文件路径不能为空");
            return;
        }

        if (ins == null) {
            log.error("要被上传的文件流不能为空");
            return;
        }


        // 获取连接
        MinioClient minioClient = gainMinioClient();
        if (minioClient == null) {
            log.error("获取minio连接失败");
            return;
        }

        minioClient.putObject(PutObjectArgs
                .builder()
                .bucket(bucketName)
                .object(filePath)
                .stream(ins, ins.available(), -1)
                .build());

        // 上传文件至指定的目录，Minio 7.0.2报错
//        minioClient.putObject(properties.getBucketName(), filePath, ins, new PutObjectOptions(ins.available(), -1L));

        //使用Minio6.0.11版本可以
//        minioClient.putObject(bucketName, objectNamePrefix + "/" + filePath,ins,Long.valueOf(ins.available()),"application/octet-stream");
    }

    /**
     * 获取指定文件的输入流 (PS:使用完毕之后记得关闭该输入流)
     *
     * @param filePath 文件路径，不能为 （空eg: 201403/1910585304069fdj.png）
     * @return InputStream 文件流
     * @throws Exception
     */
    public InputStream gainInputStream(String filePath) throws Exception {

        if (StringUtils.isBlank(filePath)) {
            log.error("文件下载路径不能为空");
            return null;
        }

        // 获取连接
        MinioClient minioClient = gainMinioClient();
        if (minioClient == null) {
            log.error("获取minio连接失败");
            return null;
        }

        return minioClient
                .getObject(GetObjectArgs
                        .builder()
                        .bucket(bucketName)
                        .object(filePath)
                        .build());
    }

    /**
     * 写出文件到指定的输出流
     *
     * @param filePath     文件路径，不能为空 （eg: 201403/1910585304069fdj.png）
     * @param outputStream 要被写出的输出流
     * @throws Exception
     */
    public void write2OutputStream(String filePath, OutputStream outputStream) throws Exception {
        InputStream ins = null;
        try {
            if (StringUtils.isBlank(filePath)) {
                log.error("文件下载路径不能为空");
                return;
            }

            if (outputStream == null) {
                log.error("输出流不能为空");
                return;
            }


            // 获取连接
            MinioClient minioClient = gainMinioClient();
            if (minioClient == null) {
                log.error("获取minio连接失败");
                return;
            }

            // 获取文件输入流
            //注意：filePath是：202049/bgmgdnhdm3eoujbt.txt
            ins = gainInputStream(filePath);
            // input -> output
            IOUtils.copy(ins, outputStream);
        } catch (Exception e) {
            throw e;
        } finally {
            if (ins != null) {
                ins.close();
            }
        }
    }


}
